package org.yly.game.rpggame.domain.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class DomainEventPublisher {

	@SuppressWarnings("rawtypes")
	private List subscribers = new ArrayList();

	private static DomainEventPublisher instence = new DomainEventPublisher();

	private DomainEventPublisher() {
	}

	public static DomainEventPublisher getInstance() {
		return instence;
	}

	public <T> void publish(final T domainEvent) {
		if (this.hasSubscribers()) {

			Class<?> eventType = domainEvent.getClass();

			@SuppressWarnings("unchecked")
			List<DomainEventSubscriber<T>> allSubscribers = this.subscribers();

			for (DomainEventSubscriber<T> subscriber : allSubscribers) {
				Class<?> subscribedToType = subscriber.subscribedToEventType();

				if (eventType == subscribedToType || subscribedToType == DomainEvent.class) {
					subscriber.handleEvent(domainEvent);
				}
			}

		}
	}

	public void publishAll(Collection<DomainEvent> domainEvents) {
		for (DomainEvent domainEvent : domainEvents) {
			this.publish(domainEvent);
		}
	}

	public void reset() {
		this.setSubscribers(null);
	}

	@SuppressWarnings("unchecked")
	public <T> void subscribe(DomainEventSubscriber<T> aSubscriber) {
		this.subscribers().add(aSubscriber);
	}

	private boolean hasSubscribers() {
		return this.subscribers() != null;
	}

	@SuppressWarnings("rawtypes")
	private List subscribers() {
		return this.subscribers;
	}

	@SuppressWarnings("rawtypes")
	private void setSubscribers(List aSubscriberList) {
		this.subscribers = aSubscriberList;
	}
}
